import pandas as pd
import json
import os
from file_utils import read_excel, save_excel

class ClinicLogConverter:
    def __init__(self, config_path="config.json"):
        """初始化门诊日志转换器"""
        self.config = self._load_config(config_path)
        self.source_df = None
        self.target_df = None
        self.result_df = None
        # 目标模板相对路径
        self.target_template_path = self.config.get("clinic_log_target_path", "templates\\门诊日志.xlsx")

    def _load_config(self, config_path):
        """加载配置文件"""
        try:
            if not os.path.isabs(config_path):
                config_path = os.path.abspath(config_path)
            with open(config_path, 'r', encoding='utf-8') as f:
                return json.load(f)
        except FileNotFoundError:
            print(f"警告: 配置文件 {config_path} 未找到，使用默认配置")
            return self._get_default_config()
        except json.JSONDecodeError:
            print(f"错误: 配置文件格式错误，使用默认配置")
            return self._get_default_config()

    def _get_default_config(self):
        """默认配置"""
        return {
            "clinic_log_field_mapping": {},
            "clinic_log_target_path": "templates\\门诊日志.xlsx"
        }

    def load_source_table(self, file_path):
        """加载源表格"""
        try:
            self.source_df = read_excel(file_path)
            print(f"成功加载源表格: {file_path}，共 {len(self.source_df)} 行")
            return True
        except Exception as e:
            print(f"加载源表格失败: {str(e)}")
            return False

    def load_target_template(self):
        """加载目标模板表格"""
        try:
            # 处理相对路径
            if not os.path.isabs(self.target_template_path):
                target_path = os.path.abspath(self.target_template_path)
            else:
                target_path = self.target_template_path
                
            if not os.path.exists(target_path):
                print(f"目标模板不存在: {target_path}")
                return False
                
            self.target_df = read_excel(target_path)
            print(f"成功加载目标模板: {target_path}，共 {len(self.target_df.columns)} 个字段")
            return True
        except Exception as e:
            print(f"加载目标模板失败: {str(e)}")
            return False

    def _map_fields(self):
        """字段匹配映射"""
        if self.source_df is None or self.target_df is None:
            raise ValueError("源表格或目标模板未加载")
            
        target_fields = self.target_df.columns.tolist()
        source_fields = self.source_df.columns.tolist()
        field_mapping = {}
        
        # 获取配置中的字段映射规则
        config_mapping = self.config.get("clinic_log_field_mapping", {})
        
        # 1. 先按字段名完全匹配
        for field in target_fields:
            if field in source_fields:
                field_mapping[field] = field
                
        # 2. 应用配置文件中的映射规则
        for source_field, target_field in config_mapping.items():
            if target_field in target_fields and target_field not in field_mapping:
                if source_field in source_fields:
                    field_mapping[target_field] = source_field
                    
        return field_mapping

    def _process_numeric_fields(self, df):
        """处理纯数字且长度超过6的值为文本格式"""
        def convert_long_numbers(value):
            # 检查是否为数字类型且不是NaN
            if pd.api.types.is_numeric_dtype(type(value)) and not pd.isna(value):
                str_value = str(int(value)) if isinstance(value, float) and value.is_integer() else str(value)
                if len(str_value) > 6:
                    return f"'{str_value}"  # 添加单引号使其成为文本格式
            return value
            
        # 对所有单元格应用处理函数
        return df.applymap(convert_long_numbers)

    def generate_clinic_log(self, output_path=None):
        """生成门诊日志表格"""
        if not self.load_target_template():
            raise FileNotFoundError("目标模板加载失败，请确保templates\\门诊日志.xlsx存在")
            
        field_mapping = self._map_fields()
        target_fields = self.target_df.columns.tolist()
        
        # 创建新表格，保留目标字段顺序
        new_rows = []
        for _, row in self.source_df.iterrows():
            new_row = {}
            for field in target_fields:
                if field in field_mapping and field_mapping[field] in row:
                    new_row[field] = row[field_mapping[field]]
                else:
                    new_row[field] = None  # 字段不匹配则为空
            new_rows.append(new_row)
            
        self.result_df = pd.DataFrame(new_rows, columns=target_fields)
        
        # 处理长数字转文本
        self.result_df = self._process_numeric_fields(self.result_df)
        
        # 保存结果
        if output_path:
            try:
                save_excel(self.result_df, output_path)
                print(f"门诊日志转换完成，保存至: {output_path}")
                return True
            except Exception as e:
                print(f"保存文件失败: {str(e)}")
                return False
        return True

def convert_clinic_log(source_file_path, output_path=None):
    """外部调用接口：转换门诊日志"""
    converter = ClinicLogConverter()
    if not converter.load_source_table(source_file_path):
        return False
        
    try:
        if output_path:
            return converter.generate_clinic_log(output_path)
        else:
            # 生成默认输出路径
            dir_name, file_name = os.path.split(source_file_path)
            new_file_name = "门诊日志_" + file_name
            default_output = os.path.join(dir_name, new_file_name)
            return converter.generate_clinic_log(default_output)
    except Exception as e:
        print(f"转换门诊日志失败: {str(e)}")
        return False